﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace OTDR_OPT
{
    /// <summary>
    /// 修正值管理
    /// </summary>
    public class FiberCorrectionManagement
    {

        private static FiberCorrectionManagement correctionManagement = null;

        //配置文件保存的完整名称
        private string FileName = System.Environment.CurrentDirectory + "\\" + "FiberCorrection.xml";

        //单例模式
        private FiberCorrectionManagement() { }

        //获取实例
        public static FiberCorrectionManagement GetInstance()
        {
            if (correctionManagement == null)
            {
                correctionManagement = new FiberCorrectionManagement();
            }
            return correctionManagement;
        }


        //保存光纤的功率值
        public void SaveFiberPowers(List<FiberPower> fiberPowerList) {
            #region 如果文件不存在，添加文件
            if (!File.Exists(FileName))
            {
                XDocument xDoc = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                    new XElement("Config"));
                xDoc.Save(FileName);
            }
            #endregion
            XElement root = XElement.Load(FileName);
            #region 遍历清单中的所有功率值，如果不存在该节点则新增节点，否则更新节点内容
            foreach (FiberPower fiberPower in fiberPowerList)
            {
                root = XElement.Load(FileName);
                string wavelength = fiberPower.Wavelength;
                double fiber1Power = fiberPower.Fiber1Power;
                double fiber2Power = fiberPower.Fiber2Power;
                FiberType fiberType = fiberPower.TypeOfFiber;
                XElement wavelengthElement = GetWavelengthElement(wavelength); //获取波长对应的节点
                #region 如果不存在对应的波长节点，则添加该节点
                if (wavelengthElement == null)
                {
                    XElement nextElement = GetNextWaveElement(wavelength); //获取下一个节点
                    if (nextElement != null)
                    {
                        nextElement.AddBeforeSelf(new XElement("FibersPower", new XAttribute("Wavelength", wavelength),new XAttribute("TypeOfFiber", fiberType)));
                        nextElement.Parent.Save(FileName);
                    }
                    else
                    {
                        root.Add(new XElement("FibersPower", new XAttribute("Wavelength", wavelength), new XAttribute("TypeOfFiber", fiberType)));
                        root.Save(FileName);
                    }

                }
                #endregion
                wavelengthElement = GetWavelengthElement(wavelength); //获取波长对应的节点
                #region 添加光纤1的功率值
                XElement fiber1PowerElement = new XElement("Fiber1Power",fiber1Power);
                XElement fiber1Element = wavelengthElement.Element(fiber1PowerElement.Name);
                if (fiber1Element == null)
                {
                    wavelengthElement.Add(fiber1PowerElement);
                    fiber1Element = wavelengthElement.Element(fiber1PowerElement.Name);
                }
                else
                {
                    fiber1Element.Value = fiber1Power.ToString();
                }
                fiber1Element.Parent.Parent.Save(FileName);
                #endregion
                #region 添加光纤2的功率值
                XElement fiber2PowerElement = new XElement("Fiber2Power", fiber2Power);
                XElement fiber2Element = wavelengthElement.Element(fiber2PowerElement.Name);
                if (fiber2Element == null)
                {
                    wavelengthElement.Add(fiber2PowerElement);
                    fiber2Element = wavelengthElement.Element(fiber2PowerElement.Name);
                }
                else
                {
                    fiber2Element.Value = fiber2Power.ToString();
                }
                #endregion
                fiber2Element.Parent.Parent.Save(FileName);
            }
            #endregion

            #region 删除传入列表中不存在，本地配置文件中存在的节点
            root = XElement.Load(FileName);
            List<string> paramWavelengthList = new List<string>();
            foreach(FiberPower fiberPower in fiberPowerList)
            {
                paramWavelengthList.Add(fiberPower.Wavelength);
            }
            var wavelengthResult = (from elements in root.Elements("FibersPower")
                                    where elements.Attribute("Wavelength") != null
                                    select elements);
            List<XElement> removeList = new List<XElement>();
            foreach (XElement xElement in wavelengthResult) {
                string wavelength = xElement.Attribute("Wavelength").Value.ToString();
                if (!paramWavelengthList.Contains(wavelength))
                {
                    removeList.Add(xElement);
                }
            }
            foreach(XElement element in removeList)
            {
                element.Remove();
                root.Save(FileName);
            }

            #endregion
        }


        //获取波长的修正值，使用纤2-纤1的光功值来返回修正值
        //光纤1接入标准表，光纤2接入被测表。例如光纤1、2的值分别为：-10dBm、-11dBm，则修正值为-11-（-10）=-1，即在读取到标准表读数后，需加上这个修正值来确定纤2的真实光功率
        public double GetFiberCorrection(string wavelength) {
            XElement root = XElement.Load(FileName);
            var wavelengthResult = (from elements in root.Elements("FibersPower")
                                    where elements.Attribute("Wavelength") != null
                                    && elements.Attribute("Wavelength").Value.Equals(wavelength)
                                    select elements);
            if (wavelengthResult.Count() == 0)
            {
                return -9999;
            }
            XElement wavelengthElement = wavelengthResult.SingleOrDefault();
            string power1 = wavelengthElement.Element("Fiber1Power").Value.Trim();
            string power2 = wavelengthElement.Element("Fiber2Power").Value.Trim();
            double diff = Convert.ToDouble(power1) - Convert.ToDouble(power2);
            return Math.Round(diff,2);
        }

        //获取带有Wavelength属性的最后一个节点，如果没有带有相应属性的节点，则返回null
        private XElement GetLastElement() {
            XElement root = XElement.Load(FileName);

            var wavelengthResult = (from elements in root.Elements("FibersPower")
                                    where elements.Attribute("Wavelength") != null
                                    select elements);

            if (wavelengthResult.Count() == 0)
            {
                return null;
            }

            XElement lastElement = wavelengthResult.Last();
            return lastElement;
        }
               

        //获取比当前波长大的节点，没有比当前波长大的节点时，返回null
        private XElement GetNextWaveElement(string wavelength) {
            XElement root = XElement.Load(FileName);

            var wavelengthResult= (from elements in root.Elements("FibersPower")
                                   where elements.Attribute("Wavelength") != null
                                   select elements);

            if (wavelengthResult.Count() == 0)
            {
                return null;
            }

            foreach(XElement element in wavelengthResult)
            {
                int currentWavelength = Convert.ToInt16(element.Attribute("Wavelength").Value);
                int paramWavelength = Convert.ToInt16(wavelength);
                if (currentWavelength > paramWavelength)
                {
                    return element;
                }
            }

            return null;
        }


        //获取波长对应的节点
        private XElement GetWavelengthElement(string wavelength)
        {
            XElement root = XElement.Load(FileName);

            var wavelengthResult = (from elements in root.Elements("FibersPower")
                                    where elements.Attribute("Wavelength") != null
                                    && elements.Attribute("Wavelength").Value.Equals(wavelength)
                                    select elements);
            if (wavelengthResult.Count() == 0)
            {
                return null;
            }
            XElement resultElement = wavelengthResult.SingleOrDefault();
            return resultElement;
        }


        //获取本地文件中的光纤功率清单
        public List<FiberPower> GetFiberPowerList()
        {
            List<FiberPower> fiberPowerList = new List<FiberPower>();
            if (!File.Exists(FileName)) {
                return fiberPowerList;
            }
            XElement root = XElement.Load(FileName);
            var fiberPowerResult = (from elements in root.Elements("FibersPower")
                                    select elements);
            foreach (XElement element in fiberPowerResult) {
                string wavelength = element.Attribute("Wavelength").Value;
                string fiberTypeString = element.Attribute("TypeOfFiber").Value;
                FiberType fiberType = FiberType.Single;
                if (fiberTypeString.Equals("Multi"))
                {
                    fiberType = FiberType.Multi;
                }
                string fiber1Power = element.Element("Fiber1Power").Value;
                string fiber2Power = element.Element("Fiber2Power").Value;
                FiberPower fiberPower = new FiberPower();
                fiberPower.Wavelength = wavelength;
                fiberPower.TypeOfFiber = fiberType;
                fiberPower.Fiber1Power = Math.Round(Convert.ToDouble(fiber1Power), 2);
                fiberPower.Fiber2Power = Math.Round(Convert.ToDouble(fiber2Power), 2);
                fiberPowerList.Add(fiberPower);
            }
            return fiberPowerList;
        }

    }
}
